package com.macro.mall.wms.service.impl;

import com.github.pagehelper.PageHelper;
import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.mapper.*;
import com.macro.mall.model.*;
import com.macro.mall.mapper.InventoryPmsStockDao;
import com.macro.mall.param.CheckStorageParam;
import com.macro.mall.wms.dto.InVentoryStorageDto;
import com.macro.mall.wms.dto.WmsCheckStorageDto;
import com.macro.mall.wms.dto.WmsInventoryListParam;
import com.macro.mall.model.WmsInventoryStorageItemDTO;
import com.macro.mall.wms.service.IInventoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class InventoryServiceImpl implements IInventoryService {

    @Autowired
    private PmsSkuStockMapper pmsSkuStockMapper;

    @Autowired
    private PmsStockMapper pmsStockMapper;

    @Autowired
    private WmsInventoryStorageMapper inventoryStorageMapper;

    @Autowired
    private WmsInventoryStorageItemMapper wmsInventoryStorageItemMapper;

    @Autowired
    private InventoryPmsStockDao pmsStockDao;

    @Autowired
    private UmsStoreMapper umsStoreMapper;


    /**
     * 获取盘点商品列表
     * @author 孙晓亮
     * @Date 2020年9月14日
     * @param currentUserName
     * @param wmsCheckStorageDto
     * @return
     */
    @Override
    public List<CheckStorageVo> getCheckProductList(UmsAdmin admin,String currentUserName, WmsCheckStorageDto wmsCheckStorageDto) {
        PageHelper.startPage(wmsCheckStorageDto.getPageNum(), wmsCheckStorageDto.getPageSize());
        CheckStorageParam param = new CheckStorageParam();
        if(admin.getAdminType()==1){
            //省级管理员，可以看到他下面所有的用户的商品列表
            UmsStoreExample example = new UmsStoreExample();
            example.createCriteria().andParentIdEqualTo(admin.getId());
            List<Long> collect = this.umsStoreMapper.selectByExample(example).stream().map(UmsStore::getUserId).collect(Collectors.toList());
            param.setMemberIdList(collect);
        }else if(admin.getAdminType()==2){
            param.setMemberId(admin.getId());
        }
        if (!StringUtils.isEmpty(wmsCheckStorageDto.getKeyword())) {
            param.setName("%" + wmsCheckStorageDto.getKeyword() + "%");
        }
        if (!StringUtils.isEmpty(wmsCheckStorageDto.getProductSn())) {
            param.setProductSn(wmsCheckStorageDto.getProductSn());
        }
        if (wmsCheckStorageDto.getProductCategoryId() != null) {
            param.setProductCategoryId(wmsCheckStorageDto.getProductCategoryId());
        }
        List<CheckStorageVo> checkStorageVoList = pmsStockDao.getCheckProductList(param);
        return checkStorageVoList;
    }


    @Override
    public List<CheckStorageVo> getStockList(UmsAdmin admin,String currentUserName, WmsCheckStorageDto wmsCheckStorageDto) {

        PageHelper.startPage(wmsCheckStorageDto.getPageNum(), wmsCheckStorageDto.getPageSize());
        CheckStorageParam param = new CheckStorageParam();
        if(admin.getAdminType()==1){
            //省级管理员，可以看到他下面所有的用户的商品列表
            UmsStoreExample example = new UmsStoreExample();
            example.createCriteria().andParentIdEqualTo(admin.getId());
            List<Long> collect = this.umsStoreMapper.selectByExample(example).stream().map(UmsStore::getUserId).collect(Collectors.toList());
            param.setMemberIdList(collect);
        }else if(admin.getAdminType()==2){
            param.setMemberId(admin.getId());
        }
        if (!StringUtils.isEmpty(wmsCheckStorageDto.getKeyword())) {
            param.setName(wmsCheckStorageDto.getKeyword());
//            param.setName("%" + wmsCheckStorageDto.getKeyword() + "%");
        }
        if (!StringUtils.isEmpty(wmsCheckStorageDto.getProductSn())) {
            param.setProductSn(wmsCheckStorageDto.getProductSn());
        }
        if (wmsCheckStorageDto.getProductCategoryId() != null) {
            param.setProductCategoryId(wmsCheckStorageDto.getProductCategoryId());
        }

        List<CheckStorageVo> checkStorageVoList = pmsStockDao.getInventoryProductList(param);

        return checkStorageVoList;
    }

    /**
     * 生成盘点单
     * @author 孙晓亮
     * @Date 2020年9月14日
     * @param wmsCreateCheckStorageDtoList
     * @return
     */
    @Override
    public CommonResult createCheck(UmsAdmin admin,List<WmsCreateCheckStorageDto> wmsCreateCheckStorageDtoList,Long storeId) {
        //插入盘点单表
        WmsInventoryStorage wmsInventoryStorage = new WmsInventoryStorage();
        wmsInventoryStorage.setCreatTime(new Date());
        wmsInventoryStorage.setMemberId(admin.getId());
        wmsInventoryStorage.setMemberUserName(admin.getUsername());
        wmsInventoryStorage.setStatus(1);
        //获取盘点单号并set进去
        wmsInventoryStorage.setInventoryStorageSn(getInventoryStorageSn());
        inventoryStorageMapper.insert(wmsInventoryStorage);
        wmsCreateCheckStorageDtoList.forEach(p->{
            //根据传递进来的pms_stock的主键id生成盘点单商品表
            WmsInventoryStorageItem wmsInventoryStorageItem = new WmsInventoryStorageItem();
            wmsInventoryStorageItem.setInventoryStorageId(wmsInventoryStorage.getId());
            wmsInventoryStorageItem.setStoreId(storeId);
            wmsInventoryStorageItem.setMemberId(admin.getId());
            wmsInventoryStorageItem.setAgentId(p.getAgentId());
            wmsInventoryStorageItem.setMemberUserName(admin.getUsername());
            wmsInventoryStorageItem.setQuantity(p.getCheckNum());
            wmsInventoryStorageItem.setSkuStockId(p.getSkuId());
            wmsInventoryStorageItem.setOldQuantity(p.getOldQuantity());
            wmsInventoryStorageItemMapper.insert(wmsInventoryStorageItem);

        });
        //改变pms_stock表中的库存数量stock
        // pmsStockMapper.updateCheckStock(wmsCreateCheckStorageDtoList);
        this.updatePmsStockInventory(wmsCreateCheckStorageDtoList);
        //计算pms_stock表中相同的sku_stock_id的stock总数量加合覆盖pms_sku_stock表中的stock数量
        this.updatePmsSkuStockInventory();
        return CommonResult.success("盘点成功");
    }


    /**
     * 查询所有的盘点单
     * @param wmsInventoryListParam
     * @return
     */
    @Override
    public CommonPage<InVentoryStorageDto> getInventoryList(WmsInventoryListParam wmsInventoryListParam) {
        PageHelper.startPage(wmsInventoryListParam.getPageNum(), wmsInventoryListParam.getPageSize());
        List<InVentoryStorageDto> result = new ArrayList<>();
        WmsInventoryStorageExample example = new WmsInventoryStorageExample();
        WmsInventoryStorageExample.Criteria criteria = example.createCriteria();
        //设置查询结束时间为当天最后一个小时
        Date date = null;
        if(wmsInventoryListParam.getEndTime()!=null){
            Calendar c = Calendar.getInstance();
            c.setTime(wmsInventoryListParam.getEndTime());
            c.add(Calendar.HOUR, 15);
            date = c.getTime(); //结果
        }

        //根据入库单code和状态模糊查询
        if (wmsInventoryListParam.getInventoryStorageSn() != null && wmsInventoryListParam.getInventoryStorageSn().equals("")) {
            criteria.andInventoryStorageSnLike("%" + wmsInventoryListParam.getInventoryStorageSn() + "%");
        }
        if(wmsInventoryListParam.getId()!=null){
            criteria.andIdEqualTo(wmsInventoryListParam.getId());
        }
        if(wmsInventoryListParam.getStartTime()!=null && wmsInventoryListParam.getEndTime()!=null){
            criteria.andCreatTimeBetween(wmsInventoryListParam.getStartTime(),date);
        }
        if(wmsInventoryListParam.getInventoryStorageSn()!=null&&wmsInventoryListParam.getInventoryStorageSn()!=""){
            criteria.andInventoryStorageSnEqualTo(wmsInventoryListParam.getInventoryStorageSn());
        }
        example.setOrderByClause("creat_time desc");
        //查询该用户所有盘点单
        List<WmsInventoryStorage> wmsInventoryStorages = inventoryStorageMapper.selectByExample(example);
        CommonPage<WmsInventoryStorage> wmsInventoryStorageCommonPage = CommonPage.restPage(wmsInventoryStorages);
        List<WmsInventoryStorage> wmsInventoryStorageList = wmsInventoryStorageCommonPage.getList();
        if (!CollectionUtils.isEmpty(wmsInventoryStorageList)) {
            for (WmsInventoryStorage storage : wmsInventoryStorageList) {
                InVentoryStorageDto inStorageDto = toDTO(storage);
                result.add(inStorageDto);
            }
        }
        CommonPage<InVentoryStorageDto> resultA = new CommonPage();
        BeanUtils.copyProperties(wmsInventoryStorageCommonPage,resultA);
        resultA.setList(result);
        return resultA;
    }

    /**
     * 查询盘点单商品
     * @param id
     * @return
     */
    @Override
    public CommonResult<List<WmsInventoryStorageItemDTO>> getInventoryStorageItems(Long id) {
       List<WmsInventoryStorageItemDTO>  wmsInventoryStorageItemDTOS = pmsStockDao.getInventoryStorageItems(id);
        return CommonResult.success(wmsInventoryStorageItemDTOS);
    }

    /**
     * 根据盘点单返回入库单和商品的封装
     *
     * @param storage
     * @return
     */
    private InVentoryStorageDto toDTO(WmsInventoryStorage storage) {
        InVentoryStorageDto dto = new InVentoryStorageDto();
        dto.setId(storage.getId());
        dto.setStatus(storage.getStatus());
        dto.setCreatTime(storage.getCreatTime());
        dto.setInventoryStorageSn(storage.getInventoryStorageSn());
        dto.setMemberId(storage.getMemberId());
        dto.setMemberUserName(storage.getMemberUserName());
        dto.setType(storage.getType());
        dto.setStoreId(storage.getStoreId());

        //查询该入库单下所有入库商品
        WmsInventoryStorageItemExample itemExample = new WmsInventoryStorageItemExample();
        itemExample.createCriteria().andInventoryStorageIdEqualTo(storage.getId());
        List<WmsInventoryStorageItem> items = wmsInventoryStorageItemMapper.selectByExample(itemExample);
        dto.setList(items);
        return dto;
    }
    /**
     * 盘点时改变pms_stock表中的库存数量stock
     * @param wmsCreateCheckStorageDtoList
     */
    public void updatePmsStockInventory(List<WmsCreateCheckStorageDto> wmsCreateCheckStorageDtoList){
        wmsCreateCheckStorageDtoList.forEach(p->{
            //改变pms_stock表中的库存数量stock
            // pmsStockMapper.updateCheckStock(wmsCreateCheckStorageDtoList);
            Long id = p.getId();
            Integer checkNum = p.getCheckNum();
            PmsStock pmsStock = new PmsStock();
            pmsStock.setId(id);
            pmsStock.setStock(checkNum);
            pmsStockMapper.updateByPrimaryKeySelective(pmsStock);
        });
    }

    /**
     * 盘点时计算pms_stock表中相同的sku_stock_id的stock总数量加合覆盖pms_sku_stock表中的stock数量
     */
    public void updatePmsSkuStockInventory(){
        //计算pms_stock表中相同的sku_stock_id的stock总数量加合覆盖pms_sku_stock表中的stock数量
        List<Map<String,Object>> skuCountList = pmsStockDao.skuCountList();
        skuCountList.forEach(p->{
            Long id = (Long) p.get("id");
            BigDecimal bigDecimal= (BigDecimal)p.get("stockCount");
            Integer stockCount=Integer.parseInt(bigDecimal.toString());
            PmsSkuStock pmsSkuStock = new PmsSkuStock();
            pmsSkuStock.setId(id);
            pmsSkuStock.setStock(stockCount);
            pmsSkuStockMapper.updateByPrimaryKeySelective(pmsSkuStock);
        });
    }



    /**
     * 获取盘点单的单号
     * @return
     */
    private String getInventoryStorageSn(){
        String inStorageSn = "";
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        WmsInventoryStorageExample example = new WmsInventoryStorageExample();
        example.createCriteria().andInStorageSnLike(sdf.format(date)+"%");
        List<WmsInventoryStorage> wmsInventoryStorages = inventoryStorageMapper.selectByExample(example);
        int countByDay = wmsInventoryStorages.size();
        if(countByDay == 0){
            //当天还没有新建入库单
            inStorageSn = sdf.format(date).substring(0, 8) + "000000";
        }else{
            //当天新建了countByDay条入库单，取countByDay+1作为新的编号的后缀
            inStorageSn = sdf.format(date).substring(0, 8) + String.format("%04d", countByDay);
        }
        return inStorageSn;
    }
}
